home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Frameworks / Dragonsmith 1.1.1 / CW 4.5 Update / DPasser.cp < prev    next >
Encoding:
Text File  |  1994-07-04  |  5.5 KB  |  214 lines  |  [TEXT/MMCC]

  1. /*
  2.     DPasser.c
  3.     
  4.     Pass 'odoc' events to other processes (e.g., other dragons running under the THINK C Debugger)
  5.                     
  6.     NOTE:    I'm not sure what to do about stationery handling…  Then again, who's gonna drop
  7.             stationery on a dragon?  Drop and RUN!!!
  8.     
  9.     Created    25 Apr 1992    Basic code, doesn't work
  10.     Modified    29 Aug 1992    Began a rewrite to use the new Dragonsmith
  11.                         First build (v0.1) — I'll use TMON Pro to debug it; then, when it's stable, I
  12.                             can debug it with (well, another copy of) itself!
  13.             04 Sep 1992    Added Options menu with a single item Target…
  14.             15 Jan 1994    Fixed memory leak in PassDroppings
  15.       01 Jul 1994 Francis H Schiffer, 3rd - change FilterOutMyself to use LowMem 
  16.                         accessor function LMGetCurApName(void)
  17.             
  18.     
  19.     Copyright © 1992–1994 by Paul M. Hoffman
  20.     Send comments or suggestions to paul.hoffman@umich.edu -or- dragonsmith@umich.edu
  21.     
  22.     This code may be freely used, altered, and distributed in any way you want as long as:
  23.         1.    It is GIVEN away rather than sold;
  24.         2.    This statement and the above copyright notice are left intact.
  25.     
  26. */
  27.                                     
  28. #include    "Dragon.h"
  29. #include    <EPPC.h>
  30. #include    <Packages.h>        // For IUEqualString
  31.  
  32. #define    kNoDefaultApp        FALSE
  33.  
  34. enum {
  35.     mOptions = mEdit + 1
  36. };
  37.  
  38. enum {
  39.     iChooseTarget = 1
  40. };
  41.  
  42. class DPasser: public Dragon {
  43.     
  44.     protected:
  45.         AppleEvent        odocEvent;
  46.         PortInfoRec        targetPortInfo;
  47.         TargetID            targetID;        
  48.         AEAddressDesc    targetAddress;
  49.         Boolean            haveTarget;
  50.         MenuHandle        optionsMenu;
  51.  
  52.     public:
  53.                         DPasser (void);
  54.         virtual void        Start (void);
  55.         virtual OSErr        ProcessDroppings (AEDescList *docList);    // Override
  56.         virtual OSErr        PassDroppings (AEDescList *docList);
  57.         virtual Boolean    ProcessLoneDoc (AEDescList *docList);
  58.         virtual void        AskForTarget (void);
  59.     
  60.     protected:
  61.         virtual void        SetUpMenus (void);
  62.         virtual void        DoMenu (long menuItemCode);
  63.         virtual void        DoOptionsMenu (short itemNum);
  64. };
  65.  
  66. // Filter function for PPCBrowser —
  67.     pascal Boolean FilterOutMyself (LocationNameRec *locName, PortInfoRec *portInfo);
  68.  
  69. Dragon *CreateGDragon (void)
  70. {
  71.     return (Dragon *) new DPasser;
  72. }
  73.  
  74. DPasser::DPasser (void)
  75. {
  76.     targetAddress.descriptorType = typeNull;
  77.     targetAddress.dataHandle = NULL;
  78.     
  79.     HLockHi ((Handle) this);        // This simplifies a lot of things later…
  80.     
  81.     haveTarget = FALSE;
  82.  
  83.     optionsMenu = NULL;
  84. }
  85.  
  86. void DPasser::Start (void)
  87. {
  88.     OSErr    err;
  89.     
  90.     inherited::Start ();
  91.     
  92.     err = PPCInit ();
  93.     if (err != noErr)
  94.         Abort (err);
  95.     
  96. }
  97.  
  98. OSErr DPasser::ProcessDroppings (AEDescList *docList)
  99. {
  100.     long            numDroppings;
  101.     OSErr        err;
  102.     AppleEvent    theEvent;
  103.     
  104.     AEDesc        srcDesc;
  105.     DescType    retType;
  106.     short        source;
  107.     long            retSize;
  108.     
  109.     err = AEGetTheCurrentEvent (&theEvent);
  110.     err = AEGetAttributePtr (&theEvent, 'esrc', 'shor', &retType, (Ptr) &source, sizeof (source), &retSize);
  111.     
  112.     err = AECountItems (docList, &numDroppings);
  113.     if (err == noErr) {
  114.         BeginProcessing ();
  115.         if (numDroppings != 1 || !ProcessLoneDoc (docList)) {
  116.             if (!haveTarget)
  117.                 AskForTarget ();
  118.             if (haveTarget)
  119.                 err = PassDroppings (docList);
  120.         }
  121.         EndProcessing ();
  122.     }
  123.     return err;
  124. }
  125.  
  126. OSErr DPasser::PassDroppings (AEDescList *docList)
  127. {
  128.     OSErr        err;
  129.     AppleEvent    reply;
  130.     
  131.     err = AECreateAppleEvent (kCoreEventClass, kAEOpenDocuments, &targetAddress,
  132.                             kAutoGenerateReturnID, kAnyTransactionID, &odocEvent);
  133.     if (err != noErr) return err;
  134.     
  135.     err = AEPutParamDesc (&odocEvent, keyDirectObject, docList);
  136.     if (err != noErr) return err;
  137.     
  138.     err = AESend (&odocEvent, &reply, kAENoReply + kAECanInteract,
  139.                                             kAENormalPriority, 60, NULL, NULL);
  140. // BEGIN bug-fix 1.1.1
  141.     (void) AEDisposeDesc (&odocEvent);    // Don't forget to dispose of our copy of the sent event!
  142. // END bug-fix 1.1.1
  143.     
  144.     return err;
  145. }
  146.  
  147. Boolean DPasser::ProcessLoneDoc (AEDescList *docList)
  148. {
  149.     // Return TRUE if we were able to process the doc all by itself, or FALSE if there's nothing special about it
  150.  
  151.     return FALSE;        // I'll implement drag-and-drop of "special files" later
  152. }
  153.  
  154. void DPasser::AskForTarget (void)
  155. {
  156.     EventRecord        event;
  157.     OSErr            err;
  158.     unsigned char        prompt[] = "\pChoose a program to pass the event to:";        // Hard-coded string (tsk, tsk!)
  159.     unsigned char        appListLabel[] = "\pPrograms:";                        // Hard-coded string (tsk, tsk!)
  160.     AEAddressDesc    targetAddress;
  161.     
  162.     err = PPCBrowser ((ConstStr255Param) &prompt, (ConstStr255Param) &appListLabel,
  163.                 kNoDefaultApp, &targetID.location, &targetPortInfo, FilterOutMyself, NULL);
  164.     if (err == noErr) {
  165.         targetID.name = targetPortInfo.name;        // Don't worry, this is a struct copy, not an array copy
  166.         AEDisposeDesc (&this->targetAddress);    // Get rid of the old target (if there was one)
  167.         err = AECreateDesc (typeTargetID, (Ptr) &targetID, sizeof (TargetID), &targetAddress);
  168.         if (err == noErr) {
  169.             this->targetAddress = targetAddress;
  170.             haveTarget = TRUE;
  171.         }
  172.     }
  173. }
  174.  
  175. void DPasser::SetUpMenus (void)
  176. {
  177.     inherited::SetUpMenus ();            // Add the Apple, File, and Edit menus
  178.  
  179.     optionsMenu = GetMenu (mOptions);
  180.     InsertMenu (optionsMenu, 0);
  181.     
  182.     DrawMenuBar ();
  183. }
  184.  
  185. void DPasser::DoMenu (long menuItemCode)
  186. {
  187.     short    menuID, itemNum;
  188.  
  189.     menuID = menuItemCode >> 16;
  190.     itemNum = menuItemCode & 0xFFFF;
  191.  
  192.     if (menuID == mOptions)
  193.         DoOptionsMenu (itemNum);
  194.     else
  195.         inherited::DoMenu (menuItemCode);
  196. }
  197.  
  198. void DPasser::DoOptionsMenu (short itemNum)
  199. {
  200.     switch (itemNum) {
  201.         case iChooseTarget:
  202.             AskForTarget ();
  203.             break;
  204.         default:
  205.             break;
  206.     }
  207. }
  208.  
  209. pascal Boolean FilterOutMyself (LocationNameRec *locName, PortInfoRec *portInfo)
  210. {
  211.             // fhs 1994 July 4 - change to use LowMem accessor function LMGetCurApName(void)
  212.     return IUEqualString (portInfo->name.name, LMGetCurApName( ));        // IUEqualString doesn't move memory, so this is safe
  213. }
  214.